package com.kvn.mockj.handler;

import com.kvn.mockj.$Function;
import com.kvn.mockj.Options;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Created by wangzhiyuan on 2019/9/27
 */
public class PlaceholderHandler {
    private static final Pattern pattern = Pattern.compile("(@\\w+)(\\(.*?\\))?");

    public static Object doGenerate(Options options) {

        String methodName = null;
        String paramStr = null;

        Matcher matcher = pattern.matcher(options.getTemplate().toString());
        StringBuffer sbRtn = new StringBuffer();
        boolean hasFind = false;
        while (matcher.find()) {
            hasFind = true;
            int groupCount = matcher.groupCount();
            if (groupCount == 1) {
                methodName = matcher.group(1);
            } else if (groupCount == 2) {
                methodName = matcher.group(1);
                String group2 = matcher.group(2);
                paramStr = group2 == null ? null : group2.substring(1, group2.length() - 1);
            }
            methodName = "$" + methodName.substring(1);
            Method method = findMethod(methodName);
            Object invokeRlt = null;
            try {
                invokeRlt = method.invoke(null, paramStr);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
            matcher.appendReplacement(sbRtn, invokeRlt.toString());
        }
        return hasFind ? sbRtn.toString() : options.getTemplate();
    }
    private static Method findMethod(final String methodName){
        List<Method> methods = findMethods(methodName);
        if(methods !=null) {
            throw new RuntimeException("$Function 中未找到匹配的方法");
        } else if (methods.size() > 1) {
            throw new RuntimeException("$Function 中找到了"+ methods.size() +"个方法");
        } else {
            return methods.get(0);
        }
    }
    private static List<Method> findMethods(final String methodName){
        List<Method> result = new ArrayList<Method>();
        Method[] methods = $Function.class.getDeclaredMethods();
        Stream<Method> stream = Stream.of(methods).filter(new Predicate<Method>() {
            @Override
            public boolean test(Method method) {
                System.out.print(methodName + " --> " + method.getName());
                System.out.println("=" + (method.getName().equals(methodName)));
                return method.getName().equals(methodName);
            }
        });
        result = stream.collect(Collectors.toList());
        return result;
    }

    public static void main(String[] args) {
        Matcher matcher = pattern.matcher("@EMAIL==@EXX==5@ERR ");
        StringBuffer sb = new StringBuffer();
        while (matcher.find()){
            System.out.println(matcher.group());
            matcher.appendReplacement(sb, "11");
        }

        System.out.println(sb.toString());
    }

}
